package cn.huaqingcheng.tianshu.infrastructure.uc.repository;

import cn.huaqingcheng.tianshu.core.uc.model.AccountKeyValue;
import cn.huaqingcheng.tianshu.core.uc.model.AccountSettingKey;
import cn.huaqingcheng.tianshu.core.uc.repository.AccountKeyValueRepository;
import cn.huaqingcheng.tianshu.infrastructure.uc.UcConvert;
import cn.huaqingcheng.tianshu.infrastructure.uc.entity.AccountKeyValueEntity;
import cn.huaqingcheng.tianshu.infrastructure.uc.mapper.AccountKeyValueMapper;
import cn.huaqingcheng.tianshu.mybatis.OptimisticLockTool;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import java.util.Optional;

/**
 * AccountKeyValueRepositoryImpl
 */
@Repository
@RequiredArgsConstructor
public class AccountKeyValueRepositoryImpl implements AccountKeyValueRepository {

    private final AccountKeyValueMapper keyValueMapper;

    @Override
    public AccountKeyValue save(AccountKeyValue value) {
        AccountKeyValueEntity entity = UcConvert.INSTANCE.toEntity(value);
        keyValueMapper.insert(entity);
        return UcConvert.INSTANCE.toModel(entity);
    }

    @Override
    public AccountKeyValue updateById(AccountKeyValue value) {
        AccountKeyValueEntity entity = UcConvert.INSTANCE.toEntity(value);
        int i = keyValueMapper.updateById(entity);
        OptimisticLockTool.assertion(i, value.getVersion());
        return UcConvert.INSTANCE.toModel(entity);
    }

    @Override
    public AccountKeyValue updateByKey(AccountKeyValue value, AccountSettingKey key) {
        Assert.isTrue(key.isUnique(), "");

        AccountKeyValueEntity entity = UcConvert.INSTANCE.toEntity(value);
        boolean update = new LambdaUpdateChainWrapper<>(keyValueMapper)
                .eq(AccountKeyValueEntity::getKey, key.name())
                .eq(AccountKeyValueEntity::getAccountId, value.getAccountId())
                .update(entity);
        OptimisticLockTool.assertion(update, entity.getVersion());

        return UcConvert.INSTANCE.toModel(entity);
    }


    @Override
    public Optional<AccountKeyValue> selectById(Long id) {
        return Optional.ofNullable(keyValueMapper.selectById(id))
                .map(UcConvert.INSTANCE::toModel);
    }

    @Override
    public Optional<AccountKeyValue> selectByKey(AccountSettingKey key, Long accountId) {
        Assert.isTrue(key.isUnique(), "");
        return new LambdaQueryChainWrapper<>(keyValueMapper)
                .eq(AccountKeyValueEntity::getKey, key.name())
                .eq(AccountKeyValueEntity::getAccountId, accountId)
                .oneOpt()
                .map(UcConvert.INSTANCE::toModel);
    }

}
